package com.dingzhen.convert;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.search.SearchHits;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class JacksonJsonMessageConvert implements MessageConvert {

    private final ObjectMapper objectMapper;

    public JacksonJsonMessageConvert() {
        Jackson2ObjectMapperBuilder objectMapperBuilder = new Jackson2ObjectMapperBuilder();
        objectMapperBuilder.simpleDateFormat("yyyy-MM-dd HH:mm:ss")
                .createXmlMapper(Boolean.FALSE)
                .failOnUnknownProperties(Boolean.FALSE)
                .serializationInclusion(JsonInclude.Include.NON_NULL)
                .featuresToDisable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES)
                .featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
                .indentOutput(true);
        objectMapper = objectMapperBuilder.build();
    }

    @Override
    public <T> List<T> convert(SearchHits hits, Class<T> targetClass) {
        return Arrays.stream(hits.getHits()).map(s -> fromJson(s.getSourceAsString(), targetClass)).collect(Collectors.toList());
    }

    public <T> T fromJson(String paramJson, Class<T> targetClass, Class<?>... parameterClasses) {
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(targetClass, parameterClasses);
        try {
            return objectMapper.readValue(paramJson, javaType);
        } catch (IOException e) {
            throw new ElasticsearchException(e);
        }
    }
}
